/*
 * Copyright 2023-2085 xujin <ceo@itgrail.com>
 *
 * Licensed under the Grail License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://itgrail.com/docs?id=3&catalogId=87
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.itgrail.pilot.app.command.query;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.itgrail.grail.cqrs.annotation.CmdHandler;
import com.itgrail.grail.cqrs.command.CommandExecutorI;
import com.itgrail.grail.dto.ResultData;
import com.itgrail.grail.utils.reflect.BeanMapper;
import com.itgrail.pilot.app.command.cmo.query.ListMySameLevelOKRCmd;
import com.itgrail.pilot.app.command.co.*;
import com.itgrail.pilot.app.converter.KeyResultClientConverter;
import com.itgrail.pilot.app.converter.ObjectiveClientConverter;
import com.itgrail.pilot.app.converter.OkrPeriodClientConverter;
import com.itgrail.pilot.app.converter.UserClientConverter;
import com.itgrail.pilot.domain.user.contant.OkrConstants;
import com.itgrail.pilot.infrastructure.tunnel.db.dao.*;
import com.itgrail.pilot.infrastructure.tunnel.db.dataobject.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@CmdHandler
public class ListMySameLevelOKRCmdExe implements CommandExecutorI<ResultData<OkrDetailCO>, ListMySameLevelOKRCmd> {

    @Autowired
    private OkrPeriodMapper okrPeriodMapper;

    @Autowired
    private ObjectiveMapper mapper;

    @Autowired
    private KeyResultMapper keyResultMapper;

    @Autowired
    private ObjectiveClientConverter objectiveClientConverter;

    @Autowired
    private KeyResultClientConverter keyResultClientConverter;

    @Autowired
    private OkrPeriodClientConverter okrPeriodClientConverter;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserClientConverter userClientConverter;

    @Autowired
    private ClassifyMapper classifyMapper;


    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private DepartmentUserMapper departmentUserMapper;

    @Override
    public ResultData execute(ListMySameLevelOKRCmd cmd) {
        ResultData resultData = ResultData.success(null);
        check(cmd);
        //返回结果
        Map<String, Object> result = new HashMap<>();
        //查询该周期下  当前用户的所有同级用户的okr
        Integer userId = cmd.getCurrentUserId();
        UserCO currentUserInfo = getUserInfo(userId);
        //设置部门Id:
        List<DepartmentUserDO> departmentUserDOList=departmentUserMapper.queryByUserId(userId);
        if(null!=departmentUserDOList&&departmentUserDOList.size()>0){
            DepartmentUserDO departmentUserDO= departmentUserDOList.get(0);
            currentUserInfo.setDeptId(String.valueOf(departmentUserDO.getDepartmentId()));
        }
        //拿到当前用户同级的人
        List<UserCO> userLevelInfo = getUserLevelInfo(currentUserInfo);
        //查询用户的直属上级
        //List<UserCO> userLeaderInfo = getUserLeaderInfo(currentUserInfo);
        //查询当前用户的部门层级
        UserDeptCO userDepts = getUserDeptList(currentUserInfo);
        //查询当前okr
        List<OkrDetailCO> detail = findDetail(userId, cmd.getOkrPeriodId());
        result.put("myOkrs", detail);
        result.put("sameLevelUsers", userLevelInfo);
        //result.put("leaderUsers", userLeaderInfo);
        result.put("myDepts", userDepts);
        resultData.setData(result);
        return resultData;
    }

    /**
     * 查询当前用户的部门层级
     */
    protected UserDeptCO getUserDeptList(UserCO userCO) {
        if(!StringUtils.hasText(userCO.getDeptId())){
            return null;
        }
        Integer deptId = Integer.valueOf(userCO.getDeptId());
        UserDeptCO userDeptCO = new UserDeptCO();
        userDeptCO.setDeptId(deptId);
        userDeptCO.setDeptName(userCO.getDeptName());

        List<UserDO> userDOList = userMapper.findByDeptId(deptId);
        userDeptCO.setUserList(userClientConverter.dataToClient(userDOList));

        List<UserDeptCO> childDeptList = Lists.newArrayList();
        List<DepartmentDO> deptList = departmentMapper.findChildByDeptId(deptId);
        deptList.forEach(departmentDO -> {
            childDeptList.add(userClientConverter.dataToClient(departmentDO));
        });
        userDeptCO.setChildList(childDeptList);
        return userDeptCO;
    }

    protected boolean check(ListMySameLevelOKRCmd cmd) {
        Preconditions.checkNotNull(cmd, "cmd不能为null");
        Preconditions.checkNotNull(cmd.getOkrPeriodId(), "周期id不能为null");
        Preconditions.checkNotNull(cmd.getCurrentUserId(), "当前登录用户id不能为null");
        return true;
    }

    /**
     * 封装okr详情
     *
     * @param userId
     * @param okrPeriodId
     * @return
     */
    protected List<OkrDetailCO> findDetail(Integer userId, Integer okrPeriodId) {
        //封装返回值
        List<OkrDetailCO> result = new ArrayList<>();

        QueryWrapper<ObjectiveDO> userOkrWrapper = new QueryWrapper<>();
        userOkrWrapper.eq("okr_period_id", okrPeriodId);
        userOkrWrapper.eq("created", userId);
        List<ObjectiveDO> objectiveDOS = mapper.selectList(userOkrWrapper);
        if (!CollectionUtils.isEmpty(objectiveDOS)) {
            objectiveDOS.forEach(objectiveDO -> {
                OkrDetailCO okrDetailCO = new OkrDetailCO();
                //获取目标信息
                ObjectiveDetailCO objectiveDetailCO = objectiveClientConverter.dataToClient(objectiveDO);
                if (null != objectiveDO.getClassifyId()) {
                    ClassifyDO classifyDO = classifyMapper.selectById(objectiveDO.getClassifyId());
                    objectiveDetailCO.setClassifyName(classifyDO.getName());
                }
                okrDetailCO.setObjectiveDetailCO(objectiveDetailCO);

                //获取考核周期实体
                OkrPeriodDO okrPeriodDO = okrPeriodMapper.selectById(objectiveDO.getOkrPeriodId());
                OkrPeriodDetailCO okrPeriodDetailCO = okrPeriodClientConverter.dataToClient(okrPeriodDO);
                okrDetailCO.setOkrPeriodDetailCO(okrPeriodDetailCO);

                //获取关键成果
                QueryWrapper<KeyResultDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("deleted", OkrConstants.NOT_DELETED);
                queryWrapper.eq("objective_id", objectiveDO.getId());
                List<KeyResultDO> keyResultDOS = keyResultMapper.selectList(queryWrapper);
                List<KeyResultDetailCO> keyResultDetailCOS = keyResultClientConverter.dataToClients(keyResultDOS);
                okrDetailCO.setKeyResultDetailCO(keyResultDetailCOS);

                okrDetailCO.setUserCO(getUserInfo(userId));
                result.add(okrDetailCO);
            });

        }
        return result;
    }

    protected UserCO getUserInfo(Integer userId) {
        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserDO userDO = userMapper.selectOne(queryWrapper);
        return BeanMapper.map(userDO, UserCO.class);
    }

    /**
     * 查询到当前用户部门下同级的所有用户
     *
     * @param userCO
     * @return
     */
    protected List<UserCO> getUserLevelInfo(UserCO userCO) {
        //判断当前用户是否是部门leader  如果是  则查询同级用户
        LambdaQueryWrapper<DepartmentDO> deptDOQueryWrapper = new LambdaQueryWrapper<>();
        deptDOQueryWrapper.eq(DepartmentDO::getLeaderId, userCO.getUserId());
        List<DepartmentDO> departmentDOList=departmentMapper.selectList(deptDOQueryWrapper);
        QueryWrapper<UserDO> dingUserDOQueryWrapper = new QueryWrapper<>();
        if (null!=departmentDOList&&departmentDOList.size()>0) {
            DepartmentDO deptDO =departmentDOList.get(0);
            Integer parentId = deptDO.getParentId();
            LambdaQueryWrapper<DepartmentDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DepartmentDO::getParentId, parentId);
            queryWrapper.ne(DepartmentDO::getLeaderId, userCO.getUserId());
            List<DepartmentDO> list = departmentMapper.selectList(queryWrapper);
            List<Integer> userIds = new ArrayList<>();
            list.forEach(x -> {
                if (x.getLeaderId() != null) {
                    userIds.add(x.getLeaderId());
                }
            });
            dingUserDOQueryWrapper.in(!userIds.isEmpty(), "user_id", userIds);
            dingUserDOQueryWrapper.eq("parent_dept_id", userCO.getParentDeptId());
            List<UserDO> userDOS = userMapper.selectList(dingUserDOQueryWrapper);
            return Optional.ofNullable(userDOS).orElse(Arrays.asList())
                    .stream()
                    .map(item -> BeanMapper.map(item, UserCO.class)).collect(Collectors.toList());
        } else {
            //排除同级中所包含的上级
            if(StringUtils.hasText(userCO.getDeptId())){
                DepartmentDO userDept = departmentMapper.findByDeptId(Integer.valueOf(userCO.getDeptId()));
                List<UserDO> userDOS = userMapper.queryNoOneDepartment(userCO.getUserId(),Integer.valueOf(userCO.getDeptId()));
                List<UserCO> users = new ArrayList<>();
                if (!CollectionUtils.isEmpty(userDOS)) {
                    userDOS.forEach(x -> {
                        if (null != userDept) {
                            if (userDept.getLeaderId() != null) {
                                if (!x.getUserId().equals(userDept.getLeaderId())) {
                                    UserCO co = BeanMapper.map(x, UserCO.class);
                                    users.add(co);
                                }
                            } else {
                                UserCO co = BeanMapper.map(x, UserCO.class);
                                users.add(co);
                            }
                        }
                    });
                }
                return users;
            }

        }
        return null;
    }

    /**
     * 查询当前用户部门的上级
     *
     * @param userCO
     * @return
     */
    protected List<UserCO> getUserLeaderInfo(UserCO userCO) {
        //查询当前用户所在部门主管 如果主管为空 查询父部门主管
        LambdaQueryWrapper<DepartmentUserDO> deptDOQueryWrapper = new LambdaQueryWrapper<>();
        String deptId = userCO.getDeptId();
        deptDOQueryWrapper.eq(DepartmentUserDO::getDepartmentId, deptId);
        DepartmentUserDO deptDO = departmentUserMapper.selectOne(deptDOQueryWrapper);
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        /**
        if (deptDO != null && deptDO.getLeaderId() != null && !deptDO.getLeaderId().equals(userCO.getUserId())) {
            queryWrapper.eq("user_id", deptDO.getLeaderId());
        } else {
            queryWrapper.eq("dept_id", userCO.getParentDeptId());
        }**/
        List<UserDO> userDOS = userMapper.selectList(queryWrapper);
        return Optional.ofNullable(userDOS).orElse(Arrays.asList())
                .stream()
                .map(item -> BeanMapper.map(item, UserCO.class)).collect(Collectors.toList());
    }
}
